{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Comparison of Batch, Mini-Batch and Stochastic Gradient Descent"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook displays an animation comparing Batch, Mini-Batch and Stochastic Gradient Descent (introduced in Chapter 4). Thanks to [Daniel Ingram](https://github.com/daniel-s-ingram) who contributed this notebook."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<table align=\"left\">\n",
    "  <td>\n",
    "    <a href=\"https://colab.research.google.com/github/ageron/handson-ml3/blob/main/extra_gradient_descent_comparison.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://kaggle.com/kernels/welcome?src=https://github.com/ageron/handson-ml3/blob/main/extra_gradient_descent_comparison.ipynb\"><img src=\"https://kaggle.com/static/images/open-in-kaggle.svg\" /></a>\n",
    "  </td>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "from matplotlib.animation import FuncAnimation\n",
    "\n",
    "matplotlib.rc('animation', html='jshtml')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "m = 100\n",
    "X = 2 * np.random.rand(m, 1)\n",
    "X_b = np.c_[np.ones((m, 1)), X]\n",
    "y = 4 + 3 * X + np.random.rand(m, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def batch_gradient_descent():\n",
    "    n_iterations = 1000\n",
    "    learning_rate = 0.05\n",
    "    thetas = np.random.randn(2, 1)\n",
    "    thetas_path = [thetas]\n",
    "    for i in range(n_iterations):\n",
    "        gradients = 2 * X_b.T @ (X_b @ thetas - y) / m\n",
    "        thetas = thetas - learning_rate * gradients\n",
    "        thetas_path.append(thetas)\n",
    "\n",
    "    return thetas_path"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def stochastic_gradient_descent():\n",
    "    n_epochs = 50\n",
    "    t0, t1 = 5, 50\n",
    "    thetas = np.random.randn(2, 1)\n",
    "    thetas_path = [thetas]\n",
    "    for epoch in range(n_epochs):\n",
    "        for i in range(m):\n",
    "            random_index = np.random.randint(m)\n",
    "            xi = X_b[random_index:random_index+1]\n",
    "            yi = y[random_index:random_index+1]\n",
    "            gradients = 2 * xi.T @ (xi @ thetas - yi)\n",
    "            eta = learning_schedule(epoch * m + i, t0, t1)\n",
    "            thetas = thetas - eta * gradients\n",
    "            thetas_path.append(thetas)\n",
    "\n",
    "    return thetas_path"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def mini_batch_gradient_descent():\n",
    "    n_iterations = 50\n",
    "    minibatch_size = 20\n",
    "    t0, t1 = 200, 1000\n",
    "    thetas = np.random.randn(2, 1)\n",
    "    thetas_path = [thetas]\n",
    "    t = 0\n",
    "    for epoch in range(n_iterations):\n",
    "        shuffled_indices = np.random.permutation(m)\n",
    "        X_b_shuffled = X_b[shuffled_indices]\n",
    "        y_shuffled = y[shuffled_indices]\n",
    "        for i in range(0, m, minibatch_size):\n",
    "            t += 1\n",
    "            xi = X_b_shuffled[i : i + minibatch_size]\n",
    "            yi = y_shuffled[i : i + minibatch_size]\n",
    "            gradients = 2 * xi.T @ (xi @ thetas - yi) / minibatch_size\n",
    "            eta = learning_schedule(t, t0, t1)\n",
    "            thetas = thetas - eta * gradients\n",
    "            thetas_path.append(thetas)\n",
    "\n",
    "    return thetas_path"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def compute_mse(theta):\n",
    "    return ((X_b @ theta - y) ** 2).sum() / m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def learning_schedule(t, t0, t1):\n",
    "    return t0 / (t + t1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "theta0, theta1 = np.meshgrid(np.arange(0, 5, 0.1), np.arange(0, 5, 0.1))\n",
    "r, c = theta0.shape\n",
    "cost_map = np.array([[0 for _ in range(c)] for _ in range(r)])\n",
    "for i in range(r):\n",
    "    for j in range(c):\n",
    "        theta = np.array([theta0[i,j], theta1[i,j]])\n",
    "        cost_map[i,j] = compute_mse(theta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "exact_solution = np.linalg.inv(X_b.T @ X_b) @ X_b.T @ y\n",
    "bgd_thetas = np.array(batch_gradient_descent())\n",
    "sgd_thetas = np.array(stochastic_gradient_descent())\n",
    "mbgd_thetas = np.array(mini_batch_gradient_descent())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "bgd_len = len(bgd_thetas)\n",
    "sgd_len = len(sgd_thetas)\n",
    "mbgd_len = len(mbgd_thetas)\n",
    "n_iter = min(bgd_len, sgd_len, mbgd_len)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x360 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = plt.figure(figsize=(10, 5))\n",
    "data_ax = fig.add_subplot(121)\n",
    "cost_ax = fig.add_subplot(122)\n",
    "\n",
    "data_ax.plot(X, y, 'k.')\n",
    "\n",
    "cost_ax.plot(exact_solution[0,0], exact_solution[1,0], 'y*')\n",
    "cost_ax.pcolor(theta0, theta1, cost_map, shading='auto')\n",
    "\n",
    "i = -1\n",
    "[bgd_data_plot] = data_ax.plot(X, X_b @ bgd_thetas[i,:], 'r-')\n",
    "[bgd_cost_plot] = cost_ax.plot(bgd_thetas[:i,0], bgd_thetas[:i,1], 'r--')\n",
    "\n",
    "[sgd_data_plot] = data_ax.plot(X, X_b @ sgd_thetas[i,:], 'g-')\n",
    "[sgd_cost_plot] = cost_ax.plot(sgd_thetas[:i,0], sgd_thetas[:i,1], 'g--')\n",
    "\n",
    "[mbgd_data_plot] = data_ax.plot(X, X_b @ mbgd_thetas[i,:], 'b-')\n",
    "[mbgd_cost_plot] = cost_ax.plot(mbgd_thetas[:i,0], mbgd_thetas[:i,1], 'b--')\n",
    "\n",
    "data_ax.set_xlim([0, 2])\n",
    "data_ax.set_ylim([0, 15])\n",
    "cost_ax.set_xlim([3, 5])\n",
    "cost_ax.set_ylim([2, 5])\n",
    "\n",
    "data_ax.set_xlabel(r'$x_1$')\n",
    "data_ax.set_ylabel(r'$y$', rotation=0)\n",
    "cost_ax.set_xlabel(r'$\\theta_0$')\n",
    "cost_ax.set_ylabel(r'$\\theta_1$')\n",
    "\n",
    "data_ax.legend(('Data', 'BGD', 'SGD', 'MBGD'), loc=\"upper left\")\n",
    "cost_ax.legend(('Normal Equation', 'BGD', 'SGD', 'MBGD'), loc=\"upper left\")\n",
    "\n",
    "cost_ax.plot(exact_solution[0,0], exact_solution[1,0], 'y*')\n",
    "cost_img = cost_ax.pcolor(theta0, theta1, cost_map, shading='auto')\n",
    "fig.colorbar(cost_img)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def animate(i):\n",
    "    bgd_data_plot.set_data(X, X_b @ bgd_thetas[i,:])\n",
    "    bgd_cost_plot.set_data(bgd_thetas[:i,0], bgd_thetas[:i,1])\n",
    "\n",
    "    sgd_data_plot.set_data(X, X_b @ sgd_thetas[i,:])\n",
    "    sgd_cost_plot.set_data(sgd_thetas[:i,0], sgd_thetas[:i,1])\n",
    "\n",
    "    mbgd_data_plot.set_data(X, X_b @ mbgd_thetas[i,:])\n",
    "    mbgd_cost_plot.set_data(mbgd_thetas[:i,0], mbgd_thetas[:i,1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "FuncAnimation(fig, animate, frames=n_iter // 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
